#pragma once

#include <thread>
#include <functional>
#include <utility>
#include <stdexcept>

class Thread {
public:
  using ThreadFunc = std::function<void()>;

  explicit Thread(ThreadFunc func) : func_(std::move(func)) {}

  ~Thread() {
    if (worker_.joinable()) {
      worker_.join();
    }
  }

  void start() {
    if (started_) {
      throw std::logic_error("Thread::start() called twice");
    }
    started_ = true;

    worker_ = std::thread([fn = std::move(func_)]() mutable {
      if (fn) { // 检查 std::function<void()> 是否保存了有效的可调用对象
        fn();
      }
    });
  }

  void join() {
    if (worker_.joinable()) {
      worker_.join();
    }
  }

private:
  ThreadFunc func_;
  std::thread worker_;
  bool started_{false}; // 防止同一个 Thread 对象被重复启动
};